package com.realeyes.osmf.plugins
{
	import com.realeyes.osmf.elements.SkinContainerElement;
	import com.realeyes.osmf.elements.WatermarkProxyElement;
	import com.realeyes.osmf.events.DebugEvent;
	import com.realeyes.osmf.interfaces.IVideoShell;
	import com.realeyes.osmf.utils.PluginUtils;
	
	import flash.events.Event;
	import flash.external.ExternalInterface;
	
	import org.osmf.containers.MediaContainer;
	import org.osmf.elements.F4MElement;
	import org.osmf.elements.ProxyElement;
	import org.osmf.events.ContainerChangeEvent;
	import org.osmf.events.MediaElementEvent;
	import org.osmf.events.TimeEvent;
	import org.osmf.layout.LayoutMetadata;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactoryItem;
	import org.osmf.media.MediaFactoryItemType;
	import org.osmf.media.MediaPlayer;
	import org.osmf.media.MediaResourceBase;
	import org.osmf.media.PluginInfo;
	import org.osmf.net.NetLoader;
	import org.osmf.traits.MediaTraitType;
	import org.osmf.traits.TimeTrait;
	
	public class RESkinPluginInfo extends PluginInfo
	{
		// Plugin Namespace
		static public const NAMESPACE:String = "com.realeyes.osmf.plugins.RESkinPluginInfo";
		
		protected var _vidShell:IVideoShell;
		protected var _currentElement:MediaElement;
		protected var _currentContainer:MediaContainer;
		protected var _skinElement:SkinContainerElement;
		protected var _resource:MediaResourceBase;
		protected var _mediaPlayer:MediaPlayer;
		
		
		
		
		///////////////////////////////////////////////////
		// CONSTRUCTOR
		///////////////////////////////////////////////////
		
		public function RESkinPluginInfo( mediaFactoryItems:Vector.<MediaFactoryItem>=null, mediaElementCreationNotificationFunction:Function=null )
		{
			
			
			//pass along the default Vector of MediaFacttoryItems, and specify which notification function to use for refference plugin implementation
			super( mediaFactoryItems, elementCreatedNotification );
		}
		
		
		
		
		/**
		 * Called from super class when plugin has been initialized with the MediaFactory from which it was loaded.
		 *  
		 * @param resource	Provides acces to the Resource used to load the plugin and any associated meta data
		 * 
		 */	
		override public function initializePlugin( resource:MediaResourceBase ):void
		{
			var mediaPlayerMeta:MediaPlayer = resource.getMetadataValue( PluginUtils.MEDIA_PLAYER ) as MediaPlayer;
			if( mediaPlayerMeta )
			{
				_mediaPlayer = mediaPlayerMeta;
				
			}
			else
			{
				_mediaPlayer = new MediaPlayer();
				
			}
			
			
			//store the resource ref for use later
			_resource = resource;
			_vidShell = resource.getMetadataValue( PluginUtils.SHELL ) as IVideoShell;
			
			debug( "ControlBarPluginInfo - Initialized" );
			
		}
		
		////////////////////////////////////////////////
		//REFFERENCE PLUGIN IMPLEMENTATION
		
		/**
		 *Called whenever a MediaElement is generated by the MediaFactory which the plugin was loaded from.
		 * This method will be called for any element that was created. It will be called for elements loaded before the plugin was loaded if they exist. 
		 * @param element
		 * 
		 */
		protected function elementCreatedNotification( element:MediaElement ):void 
		{
			debug( "Element Created: " + element);
			
			if( !(element is F4MElement) && !(element is ProxyElement && (element as ProxyElement).proxiedElement is F4MElement ) )
			{
				linkElementForControl( element )
			}
			
			/*if( !(element is F4MElement) )
			{
				linkElementForControl( element );
			}*/
			
		}
		
		
		protected function linkElementForControl( element:MediaElement ):void
		{
			if( _currentElement )
			{
				_currentElement.removeEventListener( ContainerChangeEvent.CONTAINER_CHANGE, _onContainerChange );
			}
			
			_currentElement = element;
			
			trace("_mediaPlayer.media: " + _mediaPlayer.media);
			
			
			
			
			//link plugin media player to _currentElement for control linking
			_mediaPlayer.media = _currentElement;
			
			
			if( _skinElement )
			{
				_skinElement.updateExternals( _currentElement, _mediaPlayer );
			}
			
			//listen for when the element is added to the container
			_currentElement.addEventListener( ContainerChangeEvent.CONTAINER_CHANGE, _onContainerChange, false, 0, true );
		}
		
		
		////////////////////////////////////////////////
		
		private function _addElements():void
		{
			//if not already initialized, load up the skinElement
			//if(!_skinElement)
			//{
			
			_skinElement = new SkinContainerElement( _currentElement, _mediaPlayer );
			//_skinElement.mediaContainer = _currentContainer;
			_skinElement.loadFromXMLConfig( new XML( _resource.getMetadataValue( NAMESPACE ) ) );
			
			var skinLayout:LayoutMetadata = new LayoutMetadata();
			skinLayout.left = 0;
			skinLayout.right = 0;
			skinLayout.top = 0;
			skinLayout.bottom = 0;
			skinLayout.index = 100;
			_skinElement.addMetadata( LayoutMetadata.LAYOUT_NAMESPACE, skinLayout );
			//}
			if( !_currentContainer.containsMediaElement( _skinElement ) )
			{
				trace("ADD SKIN");
				_currentContainer.addMediaElement( _skinElement );
			}
		}
		
		private function _clearElements():void
		{
			if(_skinElement && _currentContainer.containsMediaElement( _skinElement ) )
			{
				trace("REMOVE SKIN");
				_currentContainer.removeMediaElement( _skinElement );
			}
		}
		
		
		private function _onContainerChange( event:ContainerChangeEvent ):void
		{
			if( event.oldContainer )
			{	
				//clear the skin element 
				_clearElements();
			}	
			
			//if the element is being added (has a newContainer) 
			if( event.newContainer )
			{
				//get a refference to the actual container the element is being used in - THIS IS COOL!!!
				_currentContainer = event.newContainer as MediaContainer;
				
				if( _currentContainer.hasEventListener( PluginUtils.HIDE_CONTROLS ) )
				{
					_currentContainer.removeEventListener( PluginUtils.HIDE_CONTROLS, _onHideControls );
					_currentContainer.removeEventListener( PluginUtils.SHOW_CONTROLS, _onShowControls );
				}
				
				_currentContainer.addEventListener( PluginUtils.HIDE_CONTROLS, _onHideControls );
				_currentContainer.addEventListener( PluginUtils.SHOW_CONTROLS, _onShowControls );
				
				
				if( _skinElement && _currentContainer.containsMediaElement( _skinElement ) )
				{
					//do nothing
				}
				else if( _skinElement && !_currentContainer.containsMediaElement( _skinElement ) )
				{

					trace("--MOVE/ADD SKIN");
					//_skinElement.container = _currentContainer;

					_currentContainer.addMediaElement( _skinElement );
				}
				else
				{
					_addElements();
				}
				/*if( _skinElement.controlBar ) //YES THIS IS A HACK - LEAVE ME ALONE (DH)
				{
				_skinElement.controlBar.currentState = "playing";
				}*/
			}
		}
		
		private function _onHideControls( event:Event ):void
		{
			_clearElements();
		}
		
		
		private function _onShowControls( event:Event ):void
		{
			if(!_skinElement)
			{
				_addElements();
			}
		}
		
		
		// ==================================================
		// Helper methods
		// ==================================================
		
		protected function debug( msg:String ):void 
		{
			//trace( msg );
			if( _vidShell )
			{
				_vidShell.debug( msg );
			}
		}
	}
}